#include "Level.hh"
#include <iostream>
#include <vector>
#include <utility>
#include "../Utils/include/Common.hh"
#include "../Utils/include/json.hpp"
using json = nlohmann::json;
using namespace std;

// 关卡类构造函数,初始化数据管理器和玩家位置
Level::Level(DataManager& dm) 
    : dataManager_(dm), playerX_(-1), playerY_(-1), currentFloor_(1) {}

// 初始化关卡地图,设置玩家初始位置
void Level::init(const std::vector<std::vector<int>>& roomGrid) {
    roomGrid_ = roomGrid;
    
    // 寻找入口(第一个非零房间)并设置玩家位置
    bool foundEntrance = false;
    for (size_t y = 0; y < roomGrid_.size() && !foundEntrance; y++) {
        for (size_t x = 0; x < roomGrid_[y].size() && !foundEntrance; x++) {
            if (roomGrid_[y][x] > 0) {
                playerX_ = x;
                playerY_ = y;
                foundEntrance = true;
            }
        }
    }
    
    if (!foundEntrance) {
        throw std::runtime_error("Invalid room grid - no entrance found");
    }
}

// 检查当前关卡是否完成
bool Level::isFinished() const {
    if (playerX_ < 0 || playerY_ < 0) return false;
    if (playerY_ >= roomGrid_.size()) return true;
    if (playerX_ >= roomGrid_[playerY_].size()) return true;
    
    int roomID = roomGrid_[playerY_][playerX_];
    return roomID == -1 || roomID == -2;
}

// 获取当前房间ID
int Level::getCurrentRoomID() const {
    if (isFinished()) return -1;
    return roomGrid_[playerY_][playerX_];
}

// 获取玩家X坐标
int Level::getPlayerX() const {
    return playerX_;
}

// 获取玩家Y坐标
int Level::getPlayerY() const {
    return playerY_;
}

// 获取可移动的方向列表
std::vector<Direction> Level::getAvailableDirections() const {
    std::vector<Direction> directions;
    
    if (!isFinished()) {
        // 检查北方
        if (playerY_ > 0 && roomGrid_[playerY_-1][playerX_] != 0) {
            directions.push_back(Direction::NORTH);
        }
        // 检查东方
        if (playerX_+1 < roomGrid_[playerY_].size() && roomGrid_[playerY_][playerX_+1] != 0) {
            directions.push_back(Direction::EAST);
        }
        // 检查南方
        if (playerY_+1 < roomGrid_.size() && roomGrid_[playerY_+1][playerX_] != 0) {
            directions.push_back(Direction::SOUTH);
        }
        // 检查西方
        if (playerX_ > 0 && roomGrid_[playerY_][playerX_-1] != 0) {
            directions.push_back(Direction::WEST);
        }
    }
    
    return directions;
}

// 移动玩家位置
bool Level::move(Direction direction) {
    switch (direction) {
        case Direction::NORTH:
            if (playerY_ > 0 && roomGrid_[playerY_-1][playerX_] != 0) {
                playerY_--;
                return true;
            }
            break;
        case Direction::EAST:
            if (playerX_+1 < roomGrid_[playerY_].size() && roomGrid_[playerY_][playerX_+1] != 0) {
                playerX_++;
                return true;
            }
            break;
        case Direction::SOUTH:
            if (playerY_+1 < roomGrid_.size() && roomGrid_[playerY_+1][playerX_] != 0) {
                playerY_++;
                return true;
            }
            break;
        case Direction::WEST:
            if (playerX_ > 0 && roomGrid_[playerY_][playerX_-1] != 0) {
                playerX_--;
                return true;
            }
            break;
    }
    return false;
}

// 将方向枚举转换为字符串
std::string Level::directionToString(Direction dir) const {
    switch (dir) {
        case Direction::NORTH: return "North";
        case Direction::EAST: return "East";
        case Direction::SOUTH: return "South";
        case Direction::WEST: return "West";
        default: return "Unknown";
    };
}

// 检查是否有下一层
bool Level::hasNextFloor() const {
    return currentFloor_ < 3 && isFinished();
}

// 加载新的楼层地图
void Level::loadFloorMap(const std::vector<std::vector<int>>& newMap) {
    roomGrid_ = newMap;
    playerX_ = -1;
    playerY_ = -1;
    for (size_t y = 0; y < roomGrid_.size(); y++) {
        for (size_t x = 0; x < roomGrid_[y].size(); x++) {
            if (roomGrid_[y][x] > 0) {
                playerX_ = x;
                playerY_ = y;
                return;
            }
        }
    }
    throw std::runtime_error("Invalid floor map - no entrance found");
}

// 获取当前楼层
int Level::getCurrentFloor() const {
    return currentFloor_;
}

// 前进到下一层
bool Level::advanceToNextFloor(const std::vector<std::vector<int>>& nextFloorMap) {
    if (currentFloor_ < 3 && isFinished()) {
        currentFloor_++;
        dataManager_.setCurrentFloor(currentFloor_);
        loadFloorMap(nextFloorMap);
        return true;
    }
    return false;
}

// 设置当前楼层
void Level::setCurrentFloor(int floor) {
    if (floor >= 1 && floor <= 3) {
        currentFloor_ = floor;
    } else {
        throw std::invalid_argument("Floor number must be between 1 and 3");
    }
}

// 显示小地图
void Level::showSmallMap() const {
    cout << "\n=== Small Map ===\n";
    for (size_t y = 0; y < roomGrid_.size(); ++y) {
        for (size_t x = 0; x < roomGrid_[y].size(); ++x) {
            if (x == playerX_ && y == playerY_) {
                cout << "P ";
            }
            else if (roomGrid_[y][x] == 0) {
                cout << "# ";
            }
            else if (roomGrid_[y][x] == -1) {
                cout << "E ";
            }
            else {
                cout << ". ";
            }
        }
        cout << endl;
    }
    cout << "P: You | E: Exit | .: Room | #: Wall\n";
    cout << "\nCompass:\n";
    cout << "   N\n";
    cout << "W     E\n";
    cout << "   S\n";
}

// 将关卡数据转换为JSON格式
json Level::toJson() const {
    json j;
    j["playerX"] = playerX_;
    j["playerY"] = playerY_;
    j["currentFloor"] = currentFloor_;
    j["roomGrid"] = roomGrid_;
    return j;
}

// 从JSON数据恢复关卡状态
void Level::fromJson(const json& j) {
    playerX_ = j.at("playerX").get<int>();
    playerY_ = j.at("playerY").get<int>();
    currentFloor_ = j.at("currentFloor").get<int>();
    roomGrid_ = j.at("roomGrid").get<std::vector<std::vector<int>>>();
}